package cn.wolfcode.shiro;


import cn.wolfcode.domain.Employee;
import cn.wolfcode.mapper.EmployeeMapper;
import cn.wolfcode.mapper.PermissionMapper;
import cn.wolfcode.mapper.RoleMapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 自定义数据源,提供数据给shiro使用的
 */
@Component
public class CrmRealm extends AuthorizingRealm {
    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    //将容器中的配置的凭证匹配器注入给当前的 Realm 对象
    //在该 Realm 中使用指定的凭证匹配器来完成密码匹配的操作
    @Autowired
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        super.setCredentialsMatcher(credentialsMatcher);
    }


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //通过token 令牌 获取到用户名
        UsernamePasswordToken token1 = (UsernamePasswordToken) token;
        //用户名
        String username = token1.getUsername();
        //查询数据库中是否存在该用户名
        Employee employee = employeeMapper.selectByName(username);
        if (employee != null) {
            //第一个参数 是用户  第二个是 用户真正的密码 第三个参数是数据源的名字()
            return new SimpleAuthenticationInfo(employee, employee.getPassword(), ByteSource.Util.bytes(employee.getName()), this.getName());
        }
        //如果存在,就把用户的用户名,密码封装到 info 中
        return null;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        //如果 框架 没有提供 PrincipalCollection  那就自己 get


        //获取当前登录用户 对象
        Employee employee = (Employee) principalCollection.getPrimaryPrincipal();
        //获取info 它里面的数据就是 权限和角色 (正确数据)
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //判断是否是 管理员
        //如果不是管理员
        if (!employee.isAdmin()) {
            //根据 id 查询员工角色编码的集合
            List<String> roles = roleMapper.selectSnByEmpId(employee.getId());
            info.addRoles(roles);
            //根据id 查询权限的集合
            List<String> expressions = permissionMapper.selectExpressionByEmpId(employee.getId());
            info.addStringPermissions(expressions);
        } else {
            //通配符
            info.addStringPermission("*:*");
            info.addRole("ADMIN");
        }
        return info;
    }


}
